package cn.mw.cmdb.view;

import cn.mw.cmdb.entity.PropertyInfo;
import cn.mw.cmdb.entity.PropertyType;
import cn.mw.cmdb.entity.PropertyTypeManage;
import cn.mw.cmdb.entity.PropertyTypeStruct;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.ModelPropertyServiceImpl;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.microMonitorCommon.util.ListMapObjUtils;
import com.google.common.base.Strings;

import java.util.*;

import static cn.mw.cmdb.entity.InstanceInfo.SearchPrefix;
import static cn.mw.cmdb.entity.PropertyInfo.allPropertyMap;
import static cn.mw.cmdb.processor.MonitorValue.modelIdKey;
import static cn.mw.cmdb.service.impl.InstanceViewImpl.financeParentId;
import static cn.mw.cmdb.util.ListSortUtil.compareValues;
import static cn.mw.cmdb.util.ValConvertUtil.strValueConvert;

/**
 * 实例外部关联转换
 */
public class InstanceListViewConverter implements ViewConvert<Object, Object> {
    public static final String key = "relationNameMap";
    public static final String serviceManage = "cmdbServiceManage";

    public static final String dataList = "relationDataList";
    public static final String exportView = "exportView";
    public static final String checkView = "checkView";
    public static final String dataListMap = "dataListMap";
    public static final String propertyListMapKey = "propertyListInfos";
    public static final String fieldListKey = "fieldList";


    /**
     * 解析List数据，获取外部关联转换数据Map
     *
     * @param context
     * @throws Exception
     */
    @Override
    public void init(ViewConvertContext context) throws Exception {
        CmdbServiceManage cmdbServiceManage = (CmdbServiceManage) context.get(serviceManage);
        ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);

        // 转换后的Map,modelId为key，value中propertyId为key
        Map<String, Map<String, PropertyInfo>> resultMap = propertyService.getPropertyInfosByModelId(new ArrayList<>());
        context.put(allPropertyMap, resultMap);
    }

    @Override
    public Object convert(Object param, ViewConvertContext context) throws Exception {
        Map<String, Map<String, PropertyInfo>> collect = (Map<String, Map<String, PropertyInfo>>) context.get(allPropertyMap);
        String type = context.getType();
        Map mapInfo = null;
        if (param instanceof Map) {
            mapInfo = (Map) param;
        } else {
            mapInfo = ListMapObjUtils.objectToMap(param);
            if(mapInfo!=null && mapInfo.get(SearchPrefix)!=null && mapInfo.get(SearchPrefix) instanceof Map){
                mapInfo.putAll((Map)mapInfo.get(SearchPrefix));
                mapInfo.remove(SearchPrefix);
            }
        }
        Map s = new LinkedHashMap();
        Map finalMapInfo = mapInfo;
        //普通模型id
        String modelId = strValueConvert(mapInfo.get(modelIdKey));
        //挂载的金融元父模型id
        String financePId = strValueConvert(mapInfo.get(financeParentId));
        //普通模型全部属性，包括继承的全部父模型属性
        Map<String, PropertyInfo> propertyMap = collect.get(modelId);
        //金融元父模型的属性
        Map<String, PropertyInfo> financeParentpropertyMap = collect.get(financePId);
        mapInfo.forEach((k, v) -> {
            PropertyInfo propertyInfo = new PropertyInfo();
            //优先使用指定的金融元父模型的属性
            if (financeParentpropertyMap != null && financeParentpropertyMap.containsKey(k)) {
                propertyInfo = financeParentpropertyMap.get(k);
            }else{
                if (propertyMap != null && propertyMap.containsKey(k)) {
                    propertyInfo = propertyMap.get(k);
                }
            }
            Object obj = v;
            String typeId = "";
            if (propertyInfo != null && propertyInfo.getPropertyTypeRef() != null) {
                typeId = propertyInfo.getPropertyTypeRef().getTypeId();
                Map<String, Object> contextParam = propertyInfo.getPropertyTypeRef().getContext();
                if (contextParam != null) {
                    contextParam.put(dataListMap, finalMapInfo);
                }
                PropertyType propertyType = PropertyTypeManage.getPropertyType(typeId);
                if (!Strings.isNullOrEmpty(type) && exportView.equals(type)) {
                    obj = propertyType.exportValue(v, contextParam);
                }else if(!Strings.isNullOrEmpty(type) && checkView.equals(type)) {
                    obj = propertyType.checkValue(v, contextParam);
                }else {
                    obj = propertyType.readValue(v, contextParam);
                }
            }
            if (PropertyTypeStruct.ID.equals(typeId)) {
                //结构体类型，将转换数据直接放入结果集中
                if (obj != null && obj instanceof Map) {
                    s.put(k,(Map) obj);
                }
            } else {
                s.put(k, obj);
            }

        });
        return s;
    }

    @Override
    public void sortList(List data, SearchParam searchParam, ViewConvertContext context) {
        if (searchParam != null && !Strings.isNullOrEmpty(searchParam.getSortName())) {
            String sortName = searchParam.getSortName();
            String sortOrder = searchParam.getSortOrder();
            boolean ASC_order = (ascSortModel.equals(sortOrder));
            // 对指定字段进行排序，为空或null的排在最后
            Collections.sort(data, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> m1, Map<String, Object> m2) {
                    Object value1 = m1.get(sortName);
                    Object value2 = m2.get(sortName);
                    return compareValues(value1, value2, ASC_order);
                }
            });
        }
    }

}
